<?php
/**
 * curl请求功能
 * @author   ：yvhsse
 * @function ：curl 请求功能
 * @Data     ：2018-06-08
 * @Time     ：22:57:23
 *
 */

namespace yvhsse;

class Http
{
    public static function __callStatic(string $name, array $arguments)
    {
        $class = new static();
        if (!method_exists($class, $name)) {
            throw new \Exception("Method {$name} not exists");
        }
        return call_user_func_array([$class, $name], $arguments);
    }

    /**
     * 静态请求方法
     * @param string             $host    请求主机
     * @param string             $path    请求路径
     * @param string             $method  请求方式
     * @param array|string|mixed $param   请求参数
     * @param array              $headers 请求头参数
     * @return false|mixed|void
     * @author: xiaochun <3204016924@qq.com>
     * @Date  ：2024-08-27 14:28
     */
    public static function staticRequest($host, $path, $method, $param, $headers = [])
    {
        $class = new static();
        $method = strtoupper($method);
        if ($method == 'GET') {
            return $class->getRequest($host, $path, $param, $headers);
        }
        if ($method == 'POST') {
            return $class->postRequest($host, $path, $param, $headers);
        }
    }

    /**
     * 保留原接口
     * @param string       $host    请求主机
     * @param string       $path    请求路径
     * @param string       $method  请求方式
     * @param array|string $param   请求参数
     * @param array        $headers 请求包头
     * @return mixed
     */
    public function request($host, $path, $method, $param, $headers = [])
    {
        $method = strtoupper($method);
        if ($method == 'GET') {
            return self::getRequest($host, $path, $param, $headers);
        }
        if ($method == 'POST') {
            return self::postRequest($host, $path, $param, $headers);
        }
    }

    /**
     * get 方式请求数据
     * @param string       $host    请求主机
     * @param string       $path    请求路径
     * @param array|string $param   请求参数
     * @param array        $headers 请求包头
     * @return bool|string
     */
    public function getRequest($host, $path, $param = [], $headers = [])
    {
        $url = $host . $path;//完整请求地址
        //请求参数处理
        if (!empty($param)) {
            if (is_array($param)) {
                $param = http_build_query($param);
            }
            $url .= '?' . $param;
        }
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_FAILONERROR, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, false);
        //https 跳过证书验证
        if (1 == strpos("$" . $host, "https://")) {
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        }
        return curl_exec($curl);
    }

    /**
     * post 方式请求数据
     * @param string       $host    请求主机
     * @param string       $path    请求路径
     * @param array|string $param   请求参数
     * @param array        $headers 请求包头
     * @return bool|string
     */
    public function postRequest($host, $path, $param, $headers = [])
    {
        $url = $host . $path;//完整请求地址
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_FAILONERROR, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, false);
        //https 跳过证书验证
        if (1 == strpos("$" . $host, "https://")) {
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        }
        //处理请求参数
        curl_setopt($curl, CURLOPT_POSTFIELDS, $param);
        $rs = curl_exec($curl);
        $error = curl_error($curl);
        if ($rs === false || !empty($error)) {
            return false;
        }
        curl_close($curl);
        return $rs;
    }

    //参数说明
    protected function document()
    {
        $domain = '';
        $method = '';
        $url = '';
        $headers = [];
        //初始化curl会话
        $curl = curl_init();
        /**
         *get请求之前参数处理
         */
        //curl_setopt 设置 cURL 传输选项
        /**
         * CURLOPT_CUSTOMREQUEST
         *      HTTP 请求时，使用自定义的 Method 来代替"GET"或"HEAD"。
         *      对 "DELETE" 或者其他更隐蔽的 HTTP 请求有用。 有效值如 "GET"，"POST"，"CONNECT"等等；
         *      也就是说，不要在这里输入整行 HTTP 请求。例如输入"GET /index_index.html HTTP/1.0\r\n\r\n"是不正确的。
         */
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
        /**
         * CURLOPT_URL
         *      需要获取的 URL 地址，也可以在curl_init() 初始化会话的时候
         */
        curl_setopt($curl, CURLOPT_URL, $url);
        /**
         *CURLOPT_HTTPHEADER
         *      设置 HTTP 头字段的数组。
         *      格式： array('Content-type: text/plain', 'Content-length: 100')
         */
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        /**
         * CURLOPT_FAILONERROR
         *      当 HTTP 状态码大于等于 400，TRUE 将将显示错误详情。 默认情况下将返回页面，忽略 HTTP 代码。
         */
        curl_setopt($curl, CURLOPT_FAILONERROR, false);
        /**
         *CURLOPT_RETURNTRANSFER
         *      TRUE 将curl_exec()获取的信息以字符串返回，而不是直接输出。
         */
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        /**
         * CURLOPT_HEADER
         *      启用时会将头文件的信息作为数据流输出。
         */
        curl_setopt($curl, CURLOPT_HEADER, false);
        /**
         * CURLOPT_SSL_VERIFYPEER
         *      FALSE 禁止 cURL 验证对等证书（peer's certificate）。要验证的交换证书可以在 CURLOPT_CAINFO 选项中设置，或在 CURLOPT_CAPATH中设置证书目录。
         *
         * CURLOPT_SSL_VERIFYHOST
         *      设置为 1 是检查服务器SSL证书中是否存在一个公用名(common name)。
         *      译者注：公用名(Common Name)一般来讲就是填写你将要申请SSL证书的域名 (domain)或子域名(sub domain)。
         *      设置成 2，会检查公用名是否存在，并且是否与提供的主机名匹配。
         *      0 为不检查名称。 在生产环境中，这个值应该是 2（默认值）。
         */
        if (1 == strpos("$" . $domain, "https://")) {
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        }
        return false;
    }
}